package com.ruoyi.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.exception.BaseException;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.domain.LanguageType;
import com.ruoyi.system.domain.LanguageValue;
import com.ruoyi.system.domain.params.LanguageKeyParams;
import com.ruoyi.system.domain.params.LanguageTypeParams;
import com.ruoyi.system.domain.params.LanguageValueParams;
import com.ruoyi.system.domain.vo.LanguageKeyVo;
import com.ruoyi.system.domain.vo.LanguageTypeVo;
import com.ruoyi.system.domain.vo.LanguageValueVo;
import com.ruoyi.system.mapper.LanguageKeyMapper;
import com.ruoyi.system.mapper.LanguageTypeMapper;
import com.ruoyi.system.mapper.LanguageValueMapper;
import com.ruoyi.system.service.ILanguageValueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

/**
 * @author qy
 * @date 2023/3/15 14:35
 */
@Service
@Slf4j
public class LanguageValueServiceImpl implements ILanguageValueService {

    @Autowired
    private LanguageValueMapper languageValueMapper;
    @Autowired
    private LanguageKeyMapper languageKeyMapper;
    @Autowired
    private LanguageTypeMapper languageTypeMapper;

    @Override
    public IPage<LanguageValueVo> queryList(Page<LanguageValueVo> page, LanguageValueParams languageValueParams) {
        return languageValueMapper.queryList(page, languageValueParams);
    }

    @Override
    public LanguageValue save(LanguageValue languageValue) {
        languageValue.setCreateBy(SecurityUtils.getUsername());
        languageValue.setUpdateBy(SecurityUtils.getUsername());
        return languageValueMapper.save(languageValue);
    }

    @Override
    public int update(LanguageValue languageValue) {
        languageValue.setUpdateBy(SecurityUtils.getUsername());
        return languageValueMapper.update(languageValue);
    }

    @Override
    public void addUpdateData(List<LanguageValueVo> languageValueVoList) {
        log.info("【公共】新增修改语言键值-开始");
        if (languageValueVoList.size() == 0) {
            return;
        } else {
            LanguageType query = new LanguageType();
            query.setCode(languageValueVoList.get(0).getTypeCode());
            query.setIsDelete("N");
            LanguageType languageType = languageTypeMapper.selectOne(query);
            if (ObjectUtil.isNull(languageType)) {
                throw new BaseException("导入语言不存在");
            }

        }
        languageValueVoList = languageValueVoList.stream().peek(languageValueVo -> {
            if (!StrUtil.isEmpty(languageValueVo.getTypeCode())) {
                languageValueVo.setTypeCode(languageValueVo.getTypeCode().trim());
            }
            if (!StrUtil.isEmpty(languageValueVo.getCode())) {
                languageValueVo.setCode(languageValueVo.getCode().trim());
            }
        }).collect(Collectors.toList());
        String typeCode = languageValueVoList.get(0).getTypeCode();
        //获取现有所有语言key
        List<LanguageKeyVo> nowLanguageKeys = languageKeyMapper.queryList(new LanguageKeyParams());
        //将导入的KEY和现有KEY比较
        Map<String, LanguageKeyVo> nowLanguageKeyMap = nowLanguageKeys.stream().collect(Collectors.toMap(LanguageKeyVo::getCode, date -> date));
        //需要新增的KEY
        List<LanguageValueVo> newKeyList = languageValueVoList.stream().filter(list -> {
            return !nowLanguageKeyMap.containsKey(list.getCode());
        }).collect(Collectors.toList());
        //去重
        newKeyList = newKeyList.stream().collect(
                collectingAndThen(
                        toCollection(() -> new TreeSet<>(Comparator.comparing(LanguageValueVo::getCode))), ArrayList::new)
        );
        //后台管理员名称
        String username = SecurityUtils.getUsername();
        log.info("【公共】新增修改语言键值-修改语言KEY排序-成功");
        if (newKeyList.size() > 0) {
            //修改语言KEY排序
            languageKeyMapper.updateSort();
            //语言key批量新增
            languageKeyMapper.insertList(newKeyList, username);
            log.info("【公共】新增修改语言键值-语言key批量新增-成功");
            //语言键值表的KEY批量新增
            languageValueMapper.insertList(newKeyList, username, typeCode);
            log.info("【公共】新增修改语言键值-语言键值表的KEY批量新增-list={}", newKeyList);
        } else {
            log.info("【公共】新增修改语言键值-没有KEY新增");
        }
        //语言键值表批量修改
        languageValueMapper.updateByList(languageValueVoList, username);
        log.info("【公共】新增修改语言键值-语言键值表批量修改-成功");
        //发消息 同步所有语言KEY
        if (newKeyList.size() > 0) {
            this.updateAllLanguageKey(newKeyList, username);
            log.info("【公共】新增修改语言键值-发送消息-同步所有语言KEY");
        }
    }

    @Override
    public void updateAllLanguageKey(List<LanguageValueVo> newKeyList, String sysUsername) {
        //后台管理员名称
        LanguageTypeParams languageTypeParams = new LanguageTypeParams();
        languageTypeParams.setIsDelete("N");
        Page<LanguageTypeVo> page = new Page<>(1, -1);
        IPage<LanguageTypeVo> languageTypes = languageTypeMapper.queryList(page, languageTypeParams, newKeyList.get(0).getTypeCode());
        languageTypes.getRecords().forEach(date -> {
            //语言键值表的KEY批量新增
            languageValueMapper.insertList(newKeyList, sysUsername, date.getCode());
        });
    }

    @Override
    @Transactional
    public void deleteByKey(String[] keys) {
        //删除语言key
        languageKeyMapper.deleteByCodes(keys);
        languageValueMapper.deleteByCodes(keys);
    }

    @Override
    public LanguageValue getById(Long id) {
        return languageValueMapper.getById(id);
    }

    @Override
    public int updateLanguageKey(String oldCode, String newCode, String username) {
       return languageValueMapper.updateLanguageKey(oldCode,newCode,username);
    }
}
